#!/bin/bash

################################################################################
# run_analysis_benchmark.sh - Benchmark Analysis Performance
#
# Measures performance of the C# to C++ conversion pipeline:
# - Time to analyze C# solution (Roslyn)
# - Time to build IR
# - Time to normalize IR
# - Time to map types
# - Time to generate C++ code
# - Total end-to-end time
# - Memory usage
# - Payload sizes
#
# Usage:
#   ./run_analysis_benchmark.sh [--solution PATH] [--iterations N]
################################################################################

set -e

# Color codes
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
NC='\033[0m'

# Default values
SOLUTION_PATH="${1:-../integration-demo/sample_csharp/DemoClasses.sln}"
ITERATIONS="${2:-5}"
OUTPUT_DIR="./results/$(date +%Y%m%d_%H%M%S)"

echo "================================================================================"
echo "CONVERSION PIPELINE BENCHMARK"
echo "================================================================================"
echo ""
echo "Solution: $SOLUTION_PATH"
echo "Iterations: $ITERATIONS"
echo "Output: $OUTPUT_DIR"
echo ""

mkdir -p "$OUTPUT_DIR"

################################################################################
# Benchmark 1: Roslyn Analysis
################################################################################
echo -e "${BLUE}[BENCHMARK 1]${NC} Roslyn Analysis Performance"
echo "Testing C# analyzer service..."

# Check if analyzer service is available
if command -v dotnet &> /dev/null; then
    ANALYZER_PATH="../csharp-analyzer-service/src/AnalyzerCli"

    if [ -d "$ANALYZER_PATH" ]; then
        echo "Using analyzer CLI: $ANALYZER_PATH"

        # Warmup
        echo "  Warmup run..."
        cd "$ANALYZER_PATH"
        dotnet run -- --solution "$SOLUTION_PATH" --output /tmp/analyzer_warmup > /dev/null 2>&1 || true
        cd - > /dev/null

        # Benchmark runs
        echo "  Running $ITERATIONS iterations..."
        total_time=0

        for i in $(seq 1 $ITERATIONS); do
            start_time=$(date +%s.%N)

            cd "$ANALYZER_PATH"
            dotnet run -- --solution "$SOLUTION_PATH" --output /tmp/analyzer_bench_$i > /dev/null 2>&1 || true
            cd - > /dev/null

            end_time=$(date +%s.%N)
            elapsed=$(echo "$end_time - $start_time" | bc)
            total_time=$(echo "$total_time + $elapsed" | bc)

            echo "    Iteration $i: ${elapsed}s"
        done

        avg_time=$(echo "scale=3; $total_time / $ITERATIONS" | bc)
        echo -e "  ${GREEN}Average time:${NC} ${avg_time}s"
        echo "$avg_time" > "$OUTPUT_DIR/roslyn_analysis_time.txt"
    else
        echo -e "  ${YELLOW}⚠ Analyzer CLI not found, skipping...${NC}"
    fi
else
    echo -e "  ${YELLOW}⚠ dotnet not found, skipping...${NC}"
fi

echo ""

################################################################################
# Benchmark 2: IR Building
################################################################################
echo -e "${BLUE}[BENCHMARK 2]${NC} IR Building Performance"
echo "Testing IR construction from JSON..."

PYTHON_SCRIPT="$OUTPUT_DIR/bench_ir_building.py"

cat > "$PYTHON_SCRIPT" << 'EOF'
import sys
import json
import time
from pathlib import Path

# Add orchestrator to path
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "cpp-orchestrator" / "src"))

try:
    from orchestrator.ir.builder import build_ir_from_roslyn_json
except ImportError:
    print("Failed to import orchestrator modules")
    sys.exit(1)

# Load sample JSON
json_path = Path(__file__).parent.parent.parent / "integration-demo" / "sample_roslyn_output.json"
with open(json_path) as f:
    roslyn_data = json.load(f)

# Benchmark
iterations = 100
total_time = 0

for _ in range(iterations):
    start = time.perf_counter()
    classes = build_ir_from_roslyn_json(roslyn_data)
    end = time.perf_counter()
    total_time += (end - start)

avg_time_ms = (total_time / iterations) * 1000
print(f"Average time: {avg_time_ms:.2f}ms")
print(f"{avg_time_ms}")
EOF

if command -v python3 &> /dev/null; then
    result=$(python3 "$PYTHON_SCRIPT" 2>&1 | tail -1)
    echo -e "  ${GREEN}Average time:${NC} ${result}ms"
    echo "$result" > "$OUTPUT_DIR/ir_building_time.txt"
else
    echo -e "  ${YELLOW}⚠ python3 not found, skipping...${NC}"
fi

echo ""

################################################################################
# Benchmark 3: IR Normalization
################################################################################
echo -e "${BLUE}[BENCHMARK 3]${NC} IR Normalization Performance"
echo "Testing property expansion and normalization..."

PYTHON_SCRIPT="$OUTPUT_DIR/bench_normalization.py"

cat > "$PYTHON_SCRIPT" << 'EOF'
import sys
import json
import time
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent / "cpp-orchestrator" / "src"))

try:
    from orchestrator.ir.builder import build_ir_from_roslyn_json
    from orchestrator.ir.normalizer import normalize_ir
except ImportError:
    print("Failed to import orchestrator modules")
    sys.exit(1)

json_path = Path(__file__).parent.parent.parent / "integration-demo" / "sample_roslyn_output.json"
with open(json_path) as f:
    roslyn_data = json.load(f)

classes = build_ir_from_roslyn_json(roslyn_data)

iterations = 100
total_time = 0

for _ in range(iterations):
    for cls in classes:
        start = time.perf_counter()
        normalized = normalize_ir(cls)
        end = time.perf_counter()
        total_time += (end - start)

avg_time_ms = (total_time / (iterations * len(classes))) * 1000
print(f"Average time per class: {avg_time_ms:.2f}ms")
print(f"{avg_time_ms}")
EOF

if command -v python3 &> /dev/null; then
    result=$(python3 "$PYTHON_SCRIPT" 2>&1 | tail -1)
    echo -e "  ${GREEN}Average time per class:${NC} ${result}ms"
    echo "$result" > "$OUTPUT_DIR/normalization_time.txt"
else
    echo -e "  ${YELLOW}⚠ python3 not found, skipping...${NC}"
fi

echo ""

################################################################################
# Benchmark 4: Type Mapping
################################################################################
echo -e "${BLUE}[BENCHMARK 4]${NC} Type Mapping Performance"
echo "Testing C# to C++ type mapping..."

PYTHON_SCRIPT="$OUTPUT_DIR/bench_type_mapping.py"

cat > "$PYTHON_SCRIPT" << 'EOF'
import sys
import time
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent / "cpp-orchestrator" / "src"))

try:
    from orchestrator.mapping.type_mapper import TypeMapper
except ImportError:
    print("Failed to import orchestrator modules")
    sys.exit(1)

mapper = TypeMapper()

# Test various type mappings
test_types = [
    "int", "string", "bool", "double",
    "List<int>", "Dictionary<string, int>",
    "List<List<string>>", "DateTime", "string?",
    "int[]", "Dictionary<string, List<int?>>"
]

iterations = 1000
total_time = 0

for _ in range(iterations):
    for type_name in test_types:
        start = time.perf_counter()
        result = mapper.map_type(type_name)
        end = time.perf_counter()
        total_time += (end - start)

avg_time_us = (total_time / (iterations * len(test_types))) * 1_000_000
print(f"Average time per mapping: {avg_time_us:.2f}μs")
print(f"{avg_time_us}")
EOF

if command -v python3 &> /dev/null; then
    result=$(python3 "$PYTHON_SCRIPT" 2>&1 | tail -1)
    echo -e "  ${GREEN}Average time per mapping:${NC} ${result}μs"
    echo "$result" > "$OUTPUT_DIR/type_mapping_time.txt"
else
    echo -e "  ${YELLOW}⚠ python3 not found, skipping...${NC}"
fi

echo ""

################################################################################
# Benchmark 5: Code Generation
################################################################################
echo -e "${BLUE}[BENCHMARK 5]${NC} Code Generation Performance"
echo "Testing C++ code emission..."

PYTHON_SCRIPT="$OUTPUT_DIR/bench_code_generation.py"

cat > "$PYTHON_SCRIPT" << 'EOF'
import sys
import json
import time
from pathlib import Path
import tempfile

sys.path.insert(0, str(Path(__file__).parent.parent.parent / "cpp-orchestrator" / "src"))

try:
    from orchestrator.ir.builder import build_ir_from_roslyn_json
    from orchestrator.ir.normalizer import normalize_ir
    from orchestrator.codegen.emitter import CppEmitter
except ImportError:
    print("Failed to import orchestrator modules")
    sys.exit(1)

json_path = Path(__file__).parent.parent.parent / "integration-demo" / "sample_roslyn_output.json"
with open(json_path) as f:
    roslyn_data = json.load(f)

classes = build_ir_from_roslyn_json(roslyn_data)
normalized = [normalize_ir(cls) for cls in classes]

emitter = CppEmitter()

iterations = 50
total_time = 0

with tempfile.TemporaryDirectory() as tmpdir:
    for _ in range(iterations):
        for cls in normalized:
            start = time.perf_counter()
            emitter.emit_class(cls, tmpdir)
            end = time.perf_counter()
            total_time += (end - start)

avg_time_ms = (total_time / (iterations * len(normalized))) * 1000
print(f"Average time per class: {avg_time_ms:.2f}ms")
print(f"{avg_time_ms}")
EOF

if command -v python3 &> /dev/null; then
    result=$(python3 "$PYTHON_SCRIPT" 2>&1 | tail -1)
    echo -e "  ${GREEN}Average time per class:${NC} ${result}ms"
    echo "$result" > "$OUTPUT_DIR/code_generation_time.txt"
else
    echo -e "  ${YELLOW}⚠ python3 not found, skipping...${NC}"
fi

echo ""

################################################################################
# Summary
################################################################################
echo "================================================================================"
echo "BENCHMARK SUMMARY"
echo "================================================================================"
echo ""

if [ -f "$OUTPUT_DIR/roslyn_analysis_time.txt" ]; then
    echo -e "Roslyn Analysis:    $(cat $OUTPUT_DIR/roslyn_analysis_time.txt)s"
fi

if [ -f "$OUTPUT_DIR/ir_building_time.txt" ]; then
    echo -e "IR Building:        $(cat $OUTPUT_DIR/ir_building_time.txt)ms"
fi

if [ -f "$OUTPUT_DIR/normalization_time.txt" ]; then
    echo -e "Normalization:      $(cat $OUTPUT_DIR/normalization_time.txt)ms"
fi

if [ -f "$OUTPUT_DIR/type_mapping_time.txt" ]; then
    echo -e "Type Mapping:       $(cat $OUTPUT_DIR/type_mapping_time.txt)μs"
fi

if [ -f "$OUTPUT_DIR/code_generation_time.txt" ]; then
    echo -e "Code Generation:    $(cat $OUTPUT_DIR/code_generation_time.txt)ms"
fi

echo ""
echo -e "${GREEN}✅ Benchmark complete!${NC}"
echo "Results saved to: $OUTPUT_DIR"
echo ""
echo "To analyze results:"
echo "  cat $OUTPUT_DIR/*.txt"
